/* $Id: IL_cylinder_blinn_fp.cpp,v 1.5 2005/10/17 10:41:21 ovidiom Exp $ */

/**
 * @file  IL_cylinder_blinn_fp.cpp
 * @brief Contains a fragment program in string representation.
 */

namespace ILines
{
	/**
	 * @brief Fragment program for the Phong/Blinn lighting model.
	 *
	 * This fragment program evaluates the Phong/Blinn lighting model
	 * for illuminating lines.
	 */
	const char *IL_cylinder_blinn_fp =
		"!!ARBfp1.0                                             \n"
		"                                                       \n"
		"# tex0 : 2D lookup texture (diffuse term)              \n"
		"# tex1 : 2D lookup texture (specular term)             \n"
		"# tc0  : tangent vector                                \n"
		"# tc1  : light vector                                  \n"
		"# tc2  : view vector                                   \n"
		"                                                       \n"
		"# ******* attributes *********                         \n"
		"                                                       \n"
		"# texture coordinate in [0, 1]^3                       \n"
		"ATTRIB tangent = fragment.texcoord[0];                 \n"
		"ATTRIB light_v = fragment.texcoord[1];                 \n"
		"ATTRIB view    = fragment.texcoord[2];                 \n"
		"                                                       \n"
		"# ******* parameters *********                         \n"
		"                                                       \n"
		"PARAM spec_exp = state.light[0].attenuation;           \n"
		"PARAM const    = { 0, 0.5, 1, 2 };                     \n"
		"                                                       \n"
		"# ******** temporaries *********                       \n"
		"                                                       \n"
		"# tangent, normal and binormal basis                   \n"
		"TEMP tan;                                              \n"
		"TEMP nrm;                                              \n"
		"TEMP bin;                                              \n"
		"                                                       \n"
		"# halfway vector                                       \n"
		"TEMP half;                                             \n"
		"                                                       \n"
		"# ******** aliases *********                           \n"
		"                                                       \n"
		"ALIAS lu_tc = bin;                                     \n"
		"ALIAS diff  = nrm;                                     \n"
		"ALIAS spec  = tan;                                     \n"
		"ALIAS light = half;                                    \n"
		"ALIAS sqr_f = half;                                    \n"
		"                                                       \n"
		"# ******** program *********                           \n"
		"                                                       \n"
		"# compute local basis                                  \n"
		"                                                       \n"
		"# tan = tangent / |tangent|                            \n"
		"DP3 tan.w, tangent, tangent;                           \n"
		"RSQ tan.w, tan.w;                                      \n"
		"MUL tan.xyz, tangent, tan.w;                           \n"
		"                                                       \n"
		"# bin = tangent * view, bin = bin / |bin|              \n"
		"XPD bin, tangent, view;                                \n"
		"DP3 bin.w, bin, bin;                                   \n"
		"RSQ bin.w, bin.w;                                      \n"
		"MUL bin.xyz, bin, bin.w;                               \n"
		"                                                       \n"
		"# nrm = bin * tan                                      \n"
		"XPD nrm, bin, tan;                                     \n"
		"                                                       \n"
		"# compute normalized light direction                   \n"
		"DP3 light.w, light_v, light_v;                         \n"
		"RSQ light.w, light.w;                                  \n"
		"MUL light, light_v, light.w;                           \n"
		"                                                       \n"
		"# lu_tc.xy = light . { nrm, tan }                      \n"
		"DP3 lu_tc.x, light, nrm;                               \n"
		"DP3 lu_tc.y, light, tan;                               \n"
		"                                                       \n"
		"# compute normalized half vector                       \n"
		"DP3 half.w, view, view;                                \n"
		"RSQ half.w, half.w;                                    \n"
		"MAD half.xyz, view, half.w, light;                     \n"
		"DP3 half.w, half, half;                                \n"
		"RSQ half.w, half.w;                                    \n"
		"MUL half.xyz, half, half.w;                            \n"
		"                                                       \n"
		"# lu_tc.zw = half . { nrm, tan }                       \n"
		"DP3 lu_tc.z, half, nrm;                                \n"
		"DP3 lu_tc.w, half, tan;                                \n"
		"                                                       \n"
		"# 1/sqrt(1- {light, half} . tan ^ 2)                   \n"
		"MAD sqr_f.zw, lu_tc.xzyw, -lu_tc.xzyw, const.z;        \n"
		"RSQ sqr_f.z, sqr_f.z;                                  \n"
		"RSQ sqr_f.w, sqr_f.w;                                  \n"
		"MUL lu_tc.zw, lu_tc.yzxz, sqr_f;                       \n"
		"                                                       \n"
		"# make tex coords lie in [0,1]                         \n"
		"MAD lu_tc, lu_tc, const.y, const.y;                    \n"
		"                                                       \n"
		"# read diffuse factor from tex                         \n"
		"TEX diff.x, lu_tc.zyxw, texture[0], 2D;                \n"
		"                                                       \n"
		"# read spec factor from tex                            \n"
		"TEX spec.x, lu_tc.zwxy, texture[1], 2D;                \n"
		"                                                       \n"
		"# (1 - half . tan^2)^(exp/2)                           \n"
		"POW lu_tc.w, sqr_f.w, -spec_exp.w;                     \n"
		"                                                       \n"
		"MUL_SAT spec.w, spec.x, lu_tc;                         \n"
		"                                                       \n"
		"# combine                                              \n"
		"MAD result.color.xyz, diff.x, fragment.color, spec.w;  \n"
		"# keep the alpha value of the fragment                 \n"
		"MOV result.color.w, fragment.color;                    \n"
		"                                                       \n"
		"END                                                    \n";
}

